"use strict";
var root						=	"./"




var param = new jsParam(); 



//변수 var 선언전 변수 사용시 동작함(호이스팅)
//당연히 첫줄에 var로 변수들 한번 초기화 해주기
// var varInit	=	function () {
	// //단일 var 패턴
	// var	i 		= 1,
			// ex1	=	{},
			// ex2	=	"dfasdfsa";
// 			
// };
// varInit();




//loop 시 max 값은 변수로 선언하여 사용
//html collection은 비용이 매우 비쌈
// var forLoopBase	=	function () {
	// var htmlCollection		=	$("div");
	// for(var i=0, max = $(htmlCollection).length; i<max; i++){
	// }
// };
// forLoopBase();






// //for in loop
// var forInLoop	=	function () {
	// var man		=	{
							// hands	:	2,
							// legs		:	2,
							// heads	:	1
						// }
	// if(typeof Object.prototype.clone === "undefined"){
		// Object.prototype.clone = function(){};
	// }
	// for(var i in man) if(man.hasOwnProperty(i)){//프로토타입 프로퍼티를 걸러냄(ex:clone)
			// console.log(i, ":", man[i]);
	// }
// };
// forInLoop();








//prototype 사용확장시 고려하기
//ECMAScript5, 문서화, 일부 브라우저가 지원하는지 여부










//switch pattern
// var switchPatter	=	function () {
	// var 	inspectMe		=	0,
			// result			=	'';
	// switch(inspectMe){
	// case 0:
		// result	=	"zero";
		// break;
	// case 1:
		// result	=	"one";
		// break;
	// default:
		// result	=	"unknown";
	// }
// };
// switchPatter();










//암묵적 타입캐스팅 피하기
//===, !== 완전항등연산자를 사용하여 0, false, ""를 확실히 구분
// var tacitTypeCasting	=	function () {
	// var zero	=	0;
	// if(zero===false){
	// }
// 
// }
// tacitTypeCasting();







//eval 및 javascript code 문자열로 사용금지
// var avoidEval		=	function () {
	// var myFunc	=	function (o1, o2, o3) {
		// console.log("setTimeout myFunc:"+o3);
	// }
	// //setTimeout("myFunc(1,2,3)", 1000);//안티패턴
// 	
	// setTimeout(function(){
							// myFunc(1,2,3)
						// },
						// 2000
					// );
// 	
	// //아래 예제는 avoidEval함수 밖에서 실행해보아야 제대로 확인할수 있음
	// console.log(typeof un);
	// console.log(typeof deux);
	// console.log(typeof trois);
// 	
	// var jsstring	=	'var un	=	1; console.log("eval :"+un)';
	// eval(jsstring);//무개념
// 	
	// jsstring	=	'var deux	=	2; console.log("new Function :"+deux)';
	// new Function(jsstring)();
// 	
	// jsstring	=	'var trois	=	3; console.log("(function(){}) :"+trois)';
	// (function(){
		// eval(jsstring);
	// }());
// 	
// 	
	// console.log(typeof un);
	// console.log(typeof deux);
	// console.log(typeof trois);
// 	
// 	
	// (function(){
		// var local	=	1;
		// eval('local = 3; console.log(local)');//eval은 자신의 바깥쪽 유효범위에 접근 오염
		// console.log(local);
	// }());
	// (function(){
		// var local	=	1;
		// Function('console.log(typeof local)')();//Function은 어디서 실행되던 전역 유효범위를 바라본다.
	// }());
// 	
// };
// avoidEval();











/*
 * use parseInt
 * parseInt 사용시 두번째 파라메터인 기수를 지정해야 0으로 시작되는 문자열의 숫자가 0으로 파싱되는 것을 방지할 수 있음
 * 문자가 포함되지않은 숫자만 들어있는 String객체일 경우 Number를 사용하는 것이 빠름
 */

// var useParseInt	=	function () {
	// var	month	=	"06",
			// year		=	"09";
	// month			=	parseInt(month, 10);
	// year				=	parseInt(year, 10);
	// console.log(year);
// }
//useParseInt();
















/*
 * 들여쓰기
 * 중괄호 생략 금지
 * 세미콜론 생략 금지
 * 여는 중괄호는 반드시 선행하는 명령문과 같은 행에 두기
 * 하나의 생각이 완결되었다는 의미로 공백을 사용(쉼표 마침표, 콜론등 뒤에 공백사용)
 */
// var recommendIndentation	=	function () {
	// return {
		// name:"Superman"
	// };
	// /*잘못된 중괄호 위치
	// return
	// {
		// name:"Superman"
	// };
	// =>아래와 같이 해석
	// return undefined;//자바스크립특성인 개행시 자동으로 세미콜론 생성
	// {
		// name:"Superman"
	// };
	// */
// 	
	// for(var i = 0, max = 10; i < max; i += 1) {
// 		
	// }
	// var a	=	[1, 2, 3];
	// var o	=	{a: 1, b: 2};
// 	
	// function myFunc(a, b, c) {
// 		
	// }
	// var myFunc2	=	function () {
// 		
	// }
	// var	d	=	0,
			// b	=	0,
			// c	=	0,
			// a	=	b + 1;
	// if (a && b && c) {
		// d		=	a % c;
		// a		+=	d;
	// } else {
// 		
	// }
// 	
// }
// console.log(recommendIndentation());













/*
 * 명명법
 * 생성자는 대문자로 시작
 * 상수와 전역변수는 모두 대문자로
 * private method 및 propertise는 언더바로 시작
 * 
 * 
 */





















/*
 * 생성자 반환값
 * 리턴값이 없는 경우 this를 리턴
 * 리턴값이 객체가 아닐 경우 에러나지는 않고 this를 리턴
 * 객체를 리턴하면 this가 아닌 해당 객체가 리턴
 */
// var ObjectMaker	=	function(){
	// this.name	=	"this is it";
	// var that		=	{};
	// that.name	=	"And that's that";
	// return that;
// }
// var o	=	new ObjectMaker();
// console.log(o.name);










/*
 * new를 강제하는 패턴
 * 
 */
//prototype을 잃어 버림 (쓰면 않됨)
// function Waffle1(){
	// var that	=	{};
	// that.tastes	=	"yummy";
	// return that;
// }
// function Waffle2(){
	// return {
		// tastes: "yummy";
	// }
// }
//권장방법
// function Waffle(){
	// if(!(this instanceof Waffle)){
		// return new Waffle();
	// }
	// this.tastes	=	"yummy";
// }
// Waffle.prototype.wantAnother	=	true;








/*
 * 배열 판별 함수 library에 추가됨
 */
// if(typeof Array.isArray === "undefined") {
	// Array.isArray = function (arg) {
		// return Object.prototype.call(arg) === "[object Array]";
	// }
// }













/*
 * JSON parse
 */
// var jstr	=	'{"mykey": "my value"}';
// var data	= $.parseJSON(jstr);
// console.log(data.mykey);












/*
 * JSON stringify
 */
// var dog	=	{
	// name: "Fido",
	// dob: new Date(),
	// legs: [1, 2, 3, 4]
// };
// var jsonstr = $.stringify(dog);
// console.log(jsonstr);












/*
 *  정규표현식
 */
// var no_letters	=	"abc134XYZ".replace(/[a-z]/gi, "");
// console.log(no_letters);
// 
// function getRE(){
	// var re	=	/[a-z]/;
	// re.foo	=	"bar";
	// return re;
// }
// 
// var	reg	=	getRE(),
		// re2	=	getRE();
// console.log(reg===re2);
// reg.foo = "baz";
// console.log(reg.foo);
// console.log(re2.foo);











/*
 * 원시 데이터 타입 래퍼
 * 래퍼 생성자를 써도 해당 객체의 메소드가 호출될때 내부적으로 임시로 값이 객체로 변환되어 메소드가 정상 작동한다
 * 원시 데이터 타입에 확장을 해도 에러는 나지않지만 정상작동 하지 않는다.
 * 레퍼 생성자를 사용하면 프로퍼티가 생성되지만 이것을 옳지 않다
 * new를 빼먹고 래퍼 생성자를 사용하면 원시데이터 타입의 값으로 반환한다.
 */
// var nobj	=	new Number(100);
// console.log(typeof nobj);
// 
// var greet	=	new String("Hello there");
// greet.split(' ')[0];
// greet.smile	=	true;//쓰면않됨
// console.log(typeof greet.smile);












/*
 * 에러 객체
 * throw문을 통해 에러객체를 만들어 catch문에서 사용할 수 있다
 */
// try {
	// alert.okok;
	// throw{
		// name: "MyErrorType",
		// message: "에러다",
		// extra: "this was rather embarrassing",
		// remedy: genericErrorHandler,
		// remedyParams: ["okok", 1234]
	// };
// } catch (e) {
	// console.log(e.message);
	// e.remedy(e.remedyParams);
// }
// function genericErrorHandler(oParams){
	// console.log(oParams[1]);
// }






/*
 * 콜백
 */


// var findNodes = function(callback){
	// var	i			=	10000,
			// nodes	=	[],
			// found;
	// if(typeof callback !== "function"){
		// callback	=	false;
	// }
	// while(i){
		// i	-=	1;
		// if(callback){
			// callback(found);
		// }
		// nodes.push(found);
	// }
	// return nodes;
// };















/*
 * 자기 자신 재정의 함수
 */

// var scareMe	=	function(){
	// alert("boo!");
	// scareMe	=	function(){
		// alert("doble boo!");
	// };
// };
// 
// 
// scareMe.property	=	"property";
// var prank	=	scareMe;
// var spooky	=	{
	// boo:scareMe
// };
// 
// prank();
// prank();
// console.log(prank.property);
// 
// spooky.boo();
// spooky.boo();
// console.log(spooky.boo.property);
// 
// scareMe();
// scareMe();
// console.log(scareMe.property);
// 






/*
 * 즉시 실행 함수
 */
// var o	=	{
	// message:(function(){
		// var	who		=	"me",
				// what		=	"call";
		// return what + " " + who;
	// }()),
	// getMsg: function(){
		// return this.message;
	// }
// };
// 
// console.log(typeof o.getMsg);
// console.log(typeof o.message);










/*
 *  즉시 객체 초기화
 * 압축시 구글 클로저 컴파일러 사용
 * https://developers.google.com/closure/compiler/
 */
// ({
	// maxWidth: 600,
	// maxHeight: 400,
	// gimmeMax: function(){
		// return this.maxWidth + "x" + this.maxHeight;
	// },
	// init: function () {
		// console.log(this.gimmeMax());
		// //more work
	// }
// }).init();












/*
 * 함수 프로퍼티 - 메모이제이션(memoization) 패턴
 * 함수에 프로퍼티를 추가하여 결과를 캐시하면 연산반복하지않고 쓸수 있음 이를 메이모이제이션 패턴이라함
 */
// var	myFunc	 = function(){
	// console.log(result);
	// var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)), result;
	// if (!myFunc.cache[cachekey]) {
		// // work more
		// myFunc.cache[cachekey] = result;
	// }
	// return myFunc.cache[cachekey];
// };
// myFunc.cache = {};
// 




















/*
 * 설정 객체 패턴
 */
// var conf = {
	// username:	"batman",
	// fisrt:				"Bruce",
	// last:				"Wayne"
// };





















/*
 * 함수적용
 */
// var sayHi = function (who) {
	// return "Hello" + (who ? ", " + who : "") + "!";
// };
// console.log(sayHi());
// console.log('world');
// console.log(sayHi.apply(null, ["hello"]));//apply첫번째 파라메터는 함수 this와 바인딩할 객체(null일경우 전역, 객체가 있을경우 메서드로)


// var alien = {
	// sayHi: function (who) {
		// return "alien Hellow" + (who ? ", " + who : "") + "!";
	// }
// };
// console.log(alien.sayHi('world'));
// console.log(sayHi.apply(alien, ['human']));
// console.log(sayHi.call(alien, 'human'));//파라메터 하나일경우 call 사용이 편함
























/*
 * 커링(Curring) 함수가 부분적인 적용을 이해하고 처리할 수 있도록 만드는 과정을 커링이라고 한다
 */
// function add(x, y) {
	// var	oldx	=	x,
			// oldy	=	y;
	// if (typeof oldy === "undefined"){//부분적인 적용
		// return function (newy){//함수가 리턴
			// console.log(newy+ ';;;');
			// return oldx + newy;
		// };
	// }
	// //전체 인자 적용
	// return x + y;
// }
// console.log(add(1)(3));
// var add2000 = add(2000);
// console.log(add2000(12));


//위를 좀더 간단히
// function add(x, y) {
	// if(typeof y === "undefined"){
		// return function (y) {
			// return x + y;
		// };
	// }
	// return x + y;
// }


//위보다 좀 더 범용적으로
// function schonfinkelize(fn) {
	// var	slice				=	Array.prototype.slice,//arguments가 실제로는 배열이 아니기 때문에 Array.prototype.slice를 빌려오면 arguments를 배열로 바꿔 사용하기 더 편리
			// stored_args	=	slice.call(arguments, 1);
	// return function () {
		// var	new_args	=	slice.call(arguments),
				// args			=	stored_args.concat(new_args);
		// return fn.apply(null, args);
	// };
// }
// 
// 
// function add(a, b, c, d, e) {
	// return a + b + c + d + e;
// }

//함수 커링
//파라메터 여러개
// var newAdd	=	schonfinkelize(add, 5, 2, 1);
// console.log(newAdd(1, 4));
//2단계 커링
// var addOne	=	schonfinkelize(add, 1);
// console.log(addOne(10, 10, 10, 10));
// var addSix		=	schonfinkelize(addOne, 2, 3);
// console.log(addSix(5, 5));
























/*************************************************
 * 요약
 

함수의 중요한 특징
	1. 함수는 일급 객체다. 값으로 전달될 수 있고, 프로퍼티와 메서드를 확장할 수 있다.
	2. 함수는 지역 유효범위를 제공한다. 다른 중괄호 묶음은 그렇지 않다.
	로컬 변수의 선언은 로컬 유효범위의 맨 윗부분으로 호이스팅된다는 점도 기억해 두어야 한다.

함수를 생성하는 문법
	1. 기명 함수 표현식
	2. 함수 표현식.(위와 동일하지만 이름만 없는것) 익명함수라고도 한다.
	3. 함수 선언문. 다른언어의 함수 문법과 유사하다.


API패턴
	함수에 더 좋고 깔끔한 인터페이스를 제공할 수 있게 도와준다.
		1. 콜백 패턴 : 함수를 인자로 전달한다.
		2. 설정 객체 : 함수에 많은 수의 매개변수를 전달할 때 통제를 벗어나지 않도록 해준다.
		3. 함수 반환 : 함수의 반환 값이 또다시 함수 일 수 있다.
		4. 커링 : 원본 함수와 매개변수 일부를 물려받는 새로운 함수를 생성한다.


초기화 패턴
	웹페이지와 어플리케이션에서 매우 흔히 사용되는 초기화 설정작업을, 전역 네임스페이스를 어지럽히지 않고
	임시 변수를 사용해 좀더 깨끗하고 구조화된 방법으로 수행할 수 있게 도와준다.
		1. 즉시 실행 함수 : 정의되자마자 실행
		2. 즉시 객체 초기화 : 익명 객체 내부에서 초기화 작업을 구조화한 다음 즉시 호출할 수 있는 메서드를 제공한다.
		3. 초기화 시점의 분기 : 최초 코드 실행 시점에 코드를 분기하여, 애플리케이션 생명 주기 동안 계속해서 분기가 발생하지 않도록 막아준다.


성능패턴
	코드의 실행속도를 높이는 데 도움을 준다.
		1. 메모이제이션 패턴 : 함수 프로퍼티를 사용해 계산된 값을 다시 계산되지 않도록 한다.
		2. 자기선언 함수 : 자기 자신을 덮어씀으로써 두 번째 호출 이후부터는 작업량이 줄어들게 만든다.


 */
























/*
 * 네임 스페이스
 */

// var MYAPP	=	MYAPP || {};
// MYAPP.namespace = function (ns_string) {
	// var	parts		=	ns_string.split("."),
			// parent	=	MYAPP,
			// i			=	0;
	// //처음에 중복되는 전역 객체명은 제거한다
	// if (parts[0] === "MYAPP") {
		// parts	=	parts.slice(1);
	// }
	// for (i = 0; i<parts.length; i+=1) {
		// //프로퍼티 존재여부 확인후 생성
		// if (typeof parent[parts[i]] === "undefined") {
			// parent[parts[i]]	=	{};
		// }
		// parent	=	parent[parts[i]];
	// }
	// return parent;
// };
// 
// var module2	=	MYAPP.namespace("MYAPP.modules.module2");
// console.log(module2 === MYAPP.modules.module2);







































































































































































































































































































































































































































































